package com.itheima.mybatis.framework;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @author ：sean
 * @date ：Created in 2020/6/29
 * @description ：
 * @version: 1.0
 */
public class HmSqlSessionFactoryBuilder {
  /**
   * 默认构造
   * @return
   */
  public HmSqlSessionFactory build() {
    InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml");
    return new DefaultHmSqlSessionFactory(loadXmlConfig(inputStream));
  }

  /**
   * 基于xml文件
   * @param filename
   * @return
   */
  public HmSqlSessionFactory build(String filename) {
    InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filename);
    return new DefaultHmSqlSessionFactory(loadXmlConfig(inputStream));
  }

  /**
   * 基于流
   * @param inputStream
   * @return
   */
  public HmSqlSessionFactory build(InputStream inputStream) {
    return new DefaultHmSqlSessionFactory(loadXmlConfig(inputStream));
  }

  // 内部方法
  private HmConfiguration loadXmlConfig(InputStream inputStream) {
    HmConfiguration configuration = new HmConfiguration();
    try {
      // sax解析XML
      SAXReader saxReader = new SAXReader();
      Document document = saxReader.read(inputStream);
      Element root = document.getRootElement();
      List<Element> list = root.selectNodes("//property");
      for (int i = 0; i < list.size(); i++) {
        Element element =  list.get(i);
        String name = element.attributeValue("name");
        String value = element.attributeValue("value");
        if("driver".equalsIgnoreCase(name)) {
          configuration.setDriver(value);
        }
        if("url".equalsIgnoreCase(name)){
          configuration.setUrl(value);
        }
        if("username".equalsIgnoreCase(name)) {
          configuration.setUsername(value);
        }
        if("password".equalsIgnoreCase(name)) {
          configuration.setPassword(value);
        }
      }

      List<Element> mappers = root.selectNodes("//mapper");

      for (int i = 0; i < mappers.size(); i++) {
        Element element =  mappers.get(i);
        String mapperPath = element.attributeValue("resource");
        // 读取mapper文件
        loadXmlMapper(configuration,mapperPath);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }finally {
      try {
        inputStream.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return configuration;
  }
  private void loadXmlMapper(HmConfiguration configuration,String mapperPath) {
    SAXReader saxReader = new SAXReader();
    try {
      Document document = saxReader.read(this.getClass().getClassLoader().getResourceAsStream(mapperPath));
      Element root = document.getRootElement();
      String namespace = root.attributeValue("namespace");
      // 加上namespace就是UserMapper的全面名称
      try {
        // 注册类
        Class mapperClass = Class.forName(namespace);
        configuration.getMapperRegistry().addMapper(mapperClass);
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      }
      List<Element> list = root.selectNodes("//select");
      for (int i = 0; i < list.size(); i++) {
        Element element =  list.get(i);
        String id = element.attributeValue("id");
        String resultType = element.attributeValue("resultType");
        String sql = element.getText();
        HmMapper mapper = new HmMapper();
        mapper.setResultType(resultType);
        mapper.setSql(sql);
        configuration.getMappers().put(namespace + "." + id,mapper);
      }
    } catch (DocumentException e) {
      e.printStackTrace();
    }
  }
}
